<!DOCTYPE html>
<html lang="zh-cn">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <link rel="stylesheet" href="../assets/css/base.css">
</head>
<body>
    <div id="app">
        <div>
            <pre v-pre class="note">
            生命周期：一段代码从运行到结束的时间过程
            钩子函数：一段代码的执行过程，在特定时间点提供一个开发这可以自行介入的自定义代码方法
                    + vue程序运行时自动执行的函数
                    + 生命周期钩子函数中的 this 指向与当前vue实例
            
            SEO: 搜索引擎优化 - 搜索引擎其本质就是爬虫程序 - 爬虫程序是只识别HTML的程序【js、css 不运行】
                             - 通过html标签的内容描述是否符合搜索结果 - 所以需要SEO优化【程序返回给浏览器的结果最好带有关键字】

            vue生命周期钩子函数：主要四个阶段的八个钩子函数组成
                                1、创建阶段【初始化自动执行】 - 创建vue实例，并完成相关配置生成，构建响应式数据，装载相关配置
                                    beforeCreate () {},
                                    created () {},  - 用与页面初始化时的异步数据加载操作 - 做服务端渲染和浏览器渲染的兼容
                                                      异步请求初始化基本都是选择 created 原因如下：
                                                      + vue支持两种渲染模式-浏览器完全渲染-服务器渲染实例浏览器渲染页面
                                                        -> 浏览器完全渲染 : 在created，beforeMount，mounted
                                                                           钩子函数中都可以完成异步初始化请求加载操作
                                                        -> 服务器渲染实例浏览器渲染页面 : 
                                                              a) 数据需要在服务器时就完成加载(SEO) : 只能在created中进行请求
                                                              b) 数据在浏览器时才完成加载 : 在created，beforeMount，mounted 进行请求
                                2、挂载运行阶段【初始化自动执行】 - 创建当前vue实例的对应模板【虚拟DOM-vnode】
                                    beforeMount () {},
                                    mounted () {}, - 用户三方插件对应的DOM的功能初始化构建
                                3、程序运行阶段【被特定操作触发时自动执行】监控变量变化后页面有没有完成更新操作
                                    beforeUpdate () {},
                                    updated () {},
                                4、销毁阶段【被特定操作触发时自动执行】- 一般在组件开发中会用于关闭一些组件功能，例如计时器
                                    vue3  beforeUnmount(){},
                                    vue3  unmounted(){}
                                    vue2  beforeDestroy () {},
                                    vue2  destroyed () {},

                                vue3 提供的调试钩子函数【不能作为项目功能使用的，只是为开发这提供调试功能】
                                    renderTracked(){}
                                    renderTriggered(){}
    
            复习：
                $options【vue配置项】、
                $data【被劫持数据的集合对象】、
                $el【当前vue实例对应的模板容器标签】
            </pre>
            <p id="pDom" ref="pDom">arr:{{ arr }}</p>
            <p ref="msgDom">msg:{{ msg }}</p>
            <input v-model="msg" type="text" />
            <p ref="infoDom">info:{{ info }}</p>
            <input v-model="info" type="text" />
            <br>
            <br>
            <input type="button" value="销毁程序" @click="doUnmount()">
        </div>
    </div>
    <script type="module">
        // console.log(document.querySelector("#pDom"))
        import { createApp } from "../assets/vue3/vue.esm-browser.js";
        const app = createApp({       
            data() {
                return {
                    msg:"测试数据msg",
                    info:"测试数据info",
                    arr:[]
                }
            },
            computed: {
                newMsg() {
                    return this.msg + ".end" 
                }
            },
            watch: {
                msg(newValue, oldValue) {
                    console.log("msg - watch")
                }
            },
            methods: {
                printMsg() {
                    console.log(this.msg)
                },
                // 模拟异步请求方法
                loadHomeDate(){
                    setTimeout(() => {
                        this.arr = [1,2]
                    }, 2000);
                },
                doUnmount(){
                    app.unmount()
                }
            },
            beforeCreate () {
                console.group("beforeCreate-创建一个vue空对象,为后续提供vue对象支持=======>")
                console.log("vue实例vm已经构建【没有数据没有功能-空对象】:",this)
                console.log("vm已经构建-vue构建配置:",this.$options) // 配置选项已完成
                console.log("vm已经构建-未完成数据劫持:",this.$data) // 空对象
                console.log("vm已经构建-msg不存在:",this.msg) // undefined
                console.log("vm已经构建-newMsg不存在:",this.newMsg) // undefined
                console.log("vm已经构建-printMsg不存在:",this.printMsg) // undefined
                console.log("vm已经构建-模板容器未构建:",this.$el) // null
                // this.loadHomeDate();
                console.groupEnd();
            },
            created () {
                console.group("created-在空对象中构建出响应式数据和相关依赖方法以及计算属性=======>")
                console.log("vm已经构建-未完成数据劫持:",this.$data) // 包含劫持数据的对象
                console.log("vm已经构建-msg不存在:",this.msg) // 能获取
                console.log("vm已经构建-newMsg不存在:",this.newMsg) // 能获取
                console.log("vm已经构建-printMsg不存在:",this.printMsg) // 能获取
                console.log("vm已经构建-模板容器未构建:",this.$el) // null
                console.log("vm已经构建-模板容器未构建:",this.$el) // null
                console.log("vm已经构建-JS查询DOM：",document.querySelector("#pDom") ) // null
                console.log("vm已经构建-refs查询DOM：",this.$refs ) // 空对象
                // this.loadHomeDate();
                console.groupEnd();
            },
            beforeMount () {
                console.group("beforeMount-完成了模板代码加载，并未vue实例完成 vnode【虚拟DOM】的构成=======>")
                console.log("vm已经构建虚拟DOM已创建-未完成数据劫持:",this.$data) // 包含劫持数据的对象
                console.log("vm已经构建虚拟DOM已创建-模板容器未构建:",this.$el) // null
                console.log("vm已经构建虚拟DOM已创建-JS查询DOM：",document.querySelector("#pDom") ) // null
                console.log("vm已经构建虚拟DOM已创建-refs查询DOM：",this.$refs ) // 空对象
                // this.loadHomeDate();
                console.groupEnd();
            },
            mounted () {
                console.group("mounted-完成了虚拟DOM到真实DOM的转换，并写入页面=======>")
                console.log("vm已经构建页面已渲染-未完成数据劫持:",this.$data) // 包含劫持数据的对象
                console.log("vm已经构建页面已渲染-模板容器未构建:",this.$el) // null
                console.log("vm已经构建页面已渲染-JS查询DOM：",document.querySelector("#pDom") )
                console.log("vm已经构建页面已渲染-refs查询DOM：",this.$refs )
                this.loadHomeDate();
                console.groupEnd();
            },
            beforeUpdate () {
                console.group("beforeUpdate-数据更新=======>")
                console.log("vm已经构建页面已渲染-:",this.$data) // 包含劫持数据的对象 - 已完成更新的变量结果
                console.log("msgDom-textContent:",this.$refs.msgDom.textContent)
                console.log("infoDom-textContent:",this.$refs.infoDom.textContent)
                console.groupEnd();
            },
            updated () {
                console.group("updated-数据更新=======>")
                console.log("vm已经构建页面已渲染-未完成数据劫持:",this.$data) // 包含劫持数据的对象 - 已完成更新的变量结果
                console.log("msgDom-textContent:",this.$refs.msgDom.textContent)
                console.log("infoDom-textContent:",this.$refs.infoDom.textContent)
                console.groupEnd();
            },
            // beforeDestroy () {},
            // destroyed () {},
            beforeUnmount(){
                console.group("beforeUnmount-数据更新=======>")
                console.groupEnd();
            },
            unmounted(){
                console.group("unmounted-数据更新=======>")
                console.groupEnd();
            },
            renderTracked(...args){
                console.group("renderTracked-调试测试方法=======>")
                console.log(args)
                console.groupEnd();
            },
            renderTriggered(...args){
                console.group("renderTriggered-调试测试方法=======>")
                console.log(args)
                console.groupEnd();
            }
        });
        app.mount("#app")
    </script>
</body>
</html>